package com.zhangzhan.gulimallproduct.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhangzhan.gulimallcommcon.enums.product.SpuInfoPublishStatusEnum;
import com.zhangzhan.gulimallcommcon.tos.SkuCheckInventoryTo;
import com.zhangzhan.gulimallcommcon.tos.SkuDiscountsEtc;
import com.zhangzhan.gulimallcommcon.tos.SpuBoundsTo;
import com.zhangzhan.gulimallcommcon.tos.es.SkuEsModel;
import com.zhangzhan.gulimallcommcon.util.*;
import com.zhangzhan.gulimallproduct.dao.SpuInfoDao;
import com.zhangzhan.gulimallproduct.entity.*;
import com.zhangzhan.gulimallproduct.feign.CouponFeignService;
import com.zhangzhan.gulimallproduct.feign.SearchFeignService;
import com.zhangzhan.gulimallproduct.feign.WareFeignService;
import com.zhangzhan.gulimallproduct.service.*;
import com.zhangzhan.gulimallproduct.vos.SpuInfoVo;
import com.zhangzhan.gulimallproduct.vos.spu.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Service("spuInfoService")
@Slf4j
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Resource
    private SpuInfoDescService spuInfoDescService;

    @Resource
    private SpuImagesService spuImagesService;

    @Resource
    private AttrService attrService;

    @Resource
    private ProductAttrValueService productAttrValueService;
    @Resource
    private SkuInfoService skuInfoService;
    @Resource
    private SkuImagesService skuImagesService;

    @Resource
    private SkuSaleAttrValueService skuSaleAttrValueService;

    @Resource
    private CouponFeignService couponFeignService;

    @Resource
    private BrandService brandService;

    @Resource
    private CategoryService categoryService;

    @Resource
    private WareFeignService wareFeignService;

    @Resource
    private SearchFeignService searchFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<SpuInfoEntity>()
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void saveDetail(SpuSaveVo saveVo) {
        //region 1、保存spu基本信息、pms_spu_info
        SpuInfoEntity spuInfoEntity = saveSpuInfoEntity(saveVo);
        //endregion

        Long spuId = spuInfoEntity.getId();


        //region 2、保存Spu的描述图片pms_spu_info_desc
        saveSpuInfoDescEntity(saveVo, spuId);
        //endregion


        //region 3、保存spu的图片集 pms_spu_images
        saveSpuImagesEntity(saveVo, spuId);
        //endregion


        //region 4、保存spu的规格参数;pms_product_attr_value
        saveProductAttrValueEntity(saveVo, spuId);
        //endregion


        //region 5、保存spu的积分信息；gulimall_sms-> sms_spu_bounds
        saveSpuBounds(saveVo, spuId);
        //endregion


        //region 6、保存当前spu对应的所有sku信息；
        List<Skus> skus = saveVo.getSkus();
        if (CollUtil.isNotEmpty(skus)) {
            List<SkuDiscountsEtc> skuDiscountsEts = new ArrayList<>();
            for (Skus sku : skus) {

                //region 6.1）、sku的基本信息；pms_sku_info
                SkuInfoEntity skuInfoEntity = CopyBean.copyBean(sku, SkuInfoEntity.class);
                skuInfoEntity.setSpuId(spuId);
                skuInfoEntity.setBrandId(spuInfoEntity.getBrandId());
                skuInfoEntity.setCatalogId(spuInfoEntity.getCatalogId());
                if (CollUtil.isNotEmpty(sku.getImages())) {
                    sku.getImages().forEach(po -> {
                        if (po.getDefaultImg() == 1) {
                            skuInfoEntity.setSkuDefaultImg(po.getImgUrl());
                        }
                    });
                }
                skuInfoEntity.setSaleCount(0L);
                skuInfoService.save(skuInfoEntity);
                //endregion

                Long skuId = skuInfoEntity.getSkuId();

                //region 6.2）、sku的图片信息；pms_sku_images
                saveSkuImagesEntity(sku, skuId);
                //endregion


                //region  6.3）、sku的销售属性信息：pms_sku_saLe_attr_vaLue
                saveSkuSaleAttrValueEntity(sku, skuId);
                //endregion

                // 6.4）、sku的优惠、满减等信息；guLimaLL_sms->sms_sku_Ladder\sms_sku_fuLL_reduction\sms_member_price
                if (sku.getFullCount() > 0 || sku.getFullPrice().compareTo(new BigDecimal(0)) > 0) {
                    SkuDiscountsEtc skuDiscountsEtc = CopyBean.copyBean(sku, SkuDiscountsEtc.class);
                    skuDiscountsEtc.setSkuId(skuId);
                    skuDiscountsEts.add(skuDiscountsEtc);
                }
            }

            if (CollUtil.isNotEmpty(skuDiscountsEts)) {
                R r = couponFeignService.saveSkuDiscountsEtc(skuDiscountsEts);
                if (r.getCode() != 0) {
                    log.error("远程保存sku的优惠、满减等信息");
                }
            }


        }
        //endregion


    }

    /**
     * @param saveVo
     * @param spuId
     * @return void
     * @description 5、保存spu的积分信息；gulimall_sms-> sms_spu_bounds
     * @author zhangyiheng
     * @date 2024/6/18 4:17
     */
    private void saveSpuBounds(SpuSaveVo saveVo, Long spuId) {
        Bounds bounds = saveVo.getBounds();
        if (!Objects.isNull(bounds)) {
            SpuBoundsTo spuBoundsTo = new SpuBoundsTo();
            spuBoundsTo.setSpuId(spuId);
            spuBoundsTo.setBuyBounds(bounds.getBuyBounds());
            spuBoundsTo.setGrowBounds(bounds.getGrowBounds());
            R r = couponFeignService.save(spuBoundsTo);
            if (r.getCode() != 0) {
                log.error("远程保存spu的积分信息失败");
            }
        }
    }

    /**
     * @param sku
     * @param skuId
     * @return void
     * @description 6.3）、sku的销售属性信息：pms_sku_saLe_attr_vaLue
     * @author zhangyiheng
     * @date 2024/6/18 3:17
     */
    private void saveSkuSaleAttrValueEntity(Skus sku, Long skuId) {
        List<Attr> attr = sku.getAttr();
        if (CollUtil.isNotEmpty(attr)) {
            List<SkuSaleAttrValueEntity> skuSaleAttrValueEntities = attr.stream().map(po -> {
                SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
                skuSaleAttrValueEntity.setSkuId(skuId);
                skuSaleAttrValueEntity.setAttrId(po.getAttrId());
                skuSaleAttrValueEntity.setAttrName(po.getAttrName());
                skuSaleAttrValueEntity.setAttrValue(po.getAttrValue());

                return skuSaleAttrValueEntity;
            }).toList();

            skuSaleAttrValueService.saveBatch(skuSaleAttrValueEntities);
        }
    }

    /**
     * @param sku
     * @param skuId
     * @return void
     * @description 6.2）、sku的图片信息；pms_sku_images
     * @author zhangyiheng
     * @date 2024/6/18 3:17
     */
    private void saveSkuImagesEntity(Skus sku, Long skuId) {
        List<Images> skuImages = sku.getImages();
        if (CollUtil.isNotEmpty(skuImages)) {
            List<SkuImagesEntity> skuImagesEntities = new ArrayList<>(skuImages.stream().map(po -> {
                if (StrUtil.isNotBlank(po.getImgUrl())) {
                    SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                    skuImagesEntity.setSkuId(skuId);
                    skuImagesEntity.setImgUrl(po.getImgUrl());
                    skuImagesEntity.setDefaultImg(po.getDefaultImg());
                    return skuImagesEntity;
                }
                return null;
            }).toList());
            skuImagesEntities.removeAll(Collections.singleton(null));
            skuImagesService.saveBatch(skuImagesEntities);
        }
    }

    private void saveProductAttrValueEntity(SpuSaveVo saveVo, Long spuId) {
        List<BaseAttrs> baseAttrs = saveVo.getBaseAttrs();
        if (CollUtil.isNotEmpty(baseAttrs)) {
            List<ProductAttrValueEntity> productAttrValueEntities = baseAttrs.stream().map(po -> {
                ProductAttrValueEntity productAttrValueEntity = new ProductAttrValueEntity();
                productAttrValueEntity.setSpuId(spuId);
                productAttrValueEntity.setAttrId(po.getAttrId());
                productAttrValueEntity.setAttrValue(po.getAttrValues());
                productAttrValueEntity.setQuickShow(po.getShowDesc());
                AttrEntity attr = attrService.getById(po.getAttrId());
                if (!Objects.isNull(attr)) {
                    productAttrValueEntity.setAttrName(attr.getAttrName());
                }
                return productAttrValueEntity;
            }).toList();
            productAttrValueService.saveBatch(productAttrValueEntities);
        }
    }

    /**
     * @param saveVo
     * @param spuId
     * @return void
     * @description 3、保存spu的图片集 pms_spu_images
     * @author zhangyiheng
     * @date 2024/6/18 3:16
     */
    private void saveSpuImagesEntity(SpuSaveVo saveVo, Long spuId) {
        List<SpuImagesEntity> spuImagesEntities = new ArrayList<>();
        List<String> images = saveVo.getImages();
        if (CollUtil.isNotEmpty(images)) {
            images.forEach(po -> {
                SpuImagesEntity spuImagesEntity = new SpuImagesEntity();
                spuImagesEntity.setSpuId(spuId);
                spuImagesEntity.setImgUrl(po);
                spuImagesEntities.add(spuImagesEntity);
            });
            spuImagesService.saveBatch(spuImagesEntities);
        }
    }

    /**
     * @param saveVo
     * @param spuId
     * @return void
     * @description 2、保存Spu的描述图片pms_spu_info_desc
     * @author zhangyiheng
     * @date 2024/6/18 3:16
     */
    private void saveSpuInfoDescEntity(SpuSaveVo saveVo, Long spuId) {
        SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
        spuInfoDescEntity.setSpuId(spuId);
        if (CollUtil.isNotEmpty(saveVo.getDecript())) {
            spuInfoDescEntity.setDecript(String.join(",", saveVo.getDecript()));
        }
        spuInfoDescService.save(spuInfoDescEntity);
    }

    /**
     * @param saveVo
     * @return com.zhangzhan.gulimallproduct.entity.SpuInfoEntity
     * @description 保存spu基本信息、pms_spu_info
     * @author zhangyiheng
     * @date 2024/6/18 3:15
     */
    private SpuInfoEntity saveSpuInfoEntity(SpuSaveVo saveVo) {
        SpuInfoEntity spuInfoEntity = CopyBean.copyBean(saveVo, SpuInfoEntity.class);
        spuInfoEntity.setCreateTime(DateUtil.date());
        spuInfoEntity.setUpdateTime(DateUtil.date());
        this.save(spuInfoEntity);
        return spuInfoEntity;
    }


    /**
     * @param params
     * @return com.zhangzhan.gulimallcommcon.util.PageUtils
     * @description queryPageDetail
     * @author zhangyiheng
     * @date 2024/6/18 20:39
     */
    @Override
    public PageUtils queryPageDetail(Map<String, Object> params) {
        String key = (String) params.get("key");
        Object status = params.get("status");
        Object brandId = params.get("brandId");
        Object catelogId = params.get("catelogId");

        LambdaQueryWrapper<SpuInfoEntity> wrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(key)) {
            wrapper.and(po -> {
                po.eq(SpuInfoEntity::getId, key).or().like(SpuInfoEntity::getSpuName, key);
            });
        }

        wrapper.eq(!Objects.isNull(status), SpuInfoEntity::getPublishStatus, status);
        wrapper.eq(!Objects.isNull(brandId) && !Objects.equals(brandId, "0"), SpuInfoEntity::getBrandId, brandId);
        wrapper.eq(!Objects.isNull(catelogId) && !Objects.equals(catelogId, "0"), SpuInfoEntity::getCatalogId, catelogId);

        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    /**
     * @param spuId
     * @return void
     * @description 商品上架
     * @author zhangyiheng
     * @date 2024/6/20 20:35
     */
    @Transactional
    @Override
    public void up(Long spuId) {

        //查询商品信息  过滤不需要检索的商品
        List<SkuEsModel.Attrs> attrs = getAttrs(spuId);

        //查询所有spu的sku
        List<SkuInfoEntity> skuInfoEntities = skuInfoService.list(Wrappers.<SkuInfoEntity>lambdaQuery()
                .eq(SkuInfoEntity::getSpuId, spuId));
        if (CollUtil.isNotEmpty(skuInfoEntities)) {

            // hasStock(是否有库存)
            List<Long> skuId = skuInfoEntities.stream().map(SkuInfoEntity::getSkuId).toList();
            Map<Long, Boolean> map = null;
            try {
                List<SkuCheckInventoryTo> data = wareFeignService.checkInventory(skuId);
                map = data.stream().collect(Collectors.toMap(SkuCheckInventoryTo::getSkuId, SkuCheckInventoryTo::getCheck));
            } catch (Exception e) {
                log.error("远程调用获取sku库存信息失败：" + e.getMessage());
            }

            Map<Long, Boolean> finalMap = map;
            List<SkuEsModel> skuEsModels = skuInfoEntities.stream().map(po -> {
                SkuEsModel skuEsModel = CopyBean.copyBean(po, SkuEsModel.class);

                //skuPrice skuImg hasStock(是否有库存) brandName brandImg catalogName Attrs
                skuEsModel.setSkuPrice(po.getPrice());
                skuEsModel.setSkuImg(po.getSkuDefaultImg());
                skuEsModel.setHotScore(0L);
                // hasStock(是否有库存)
                if (finalMap != null) {
                    skuEsModel.setHasStock(finalMap.get(skuEsModel.getSkuId()));
                } else {
                    skuEsModel.setHasStock(true);
                }


                BrandEntity brand = brandService.getById(po.getBrandId());
                skuEsModel.setBrandName(brand.getName());
                skuEsModel.setBrandImg(brand.getLogo());

                CategoryEntity category = categoryService.getById(skuEsModel.getCatalogId());
                skuEsModel.setCatalogName(category.getName());

                //Attrs
                skuEsModel.setAttrs(attrs);

                return skuEsModel;
            }).toList();

            // 存入es
            try {
                R r = searchFeignService.saveProduct(skuEsModels);
                if (r.getCode() > 0) {
                    log.error("商品存储失败");
                } else {
                    //修改状态
                    this.update(Wrappers.<SpuInfoEntity>lambdaUpdate()
                            .set(SpuInfoEntity::getPublishStatus, SpuInfoPublishStatusEnum.SJ_TYPE.getCode())
                            .set(SpuInfoEntity::getUpdateTime, DateUtil.date())
                            .eq(SpuInfoEntity::getId, spuId));
                }

            } catch (Exception e) {
            }

        }

    }

    @Override
    public SpuInfoVo listBySkuId(Long skuId) {
        SkuInfoEntity skuInfo = skuInfoService.getOne(Wrappers.<SkuInfoEntity>lambdaQuery()
                .eq(SkuInfoEntity::getSkuId, skuId));
        SpuInfoEntity entities = null;
        SpuInfoVo vo = null;
        if (!Objects.isNull(skuInfo)) {
            entities = this.getById(skuInfo.getSpuId());
            if (!Objects.isNull(entities)) {
                vo = CopyBean.copyBean(entities, SpuInfoVo.class);
                BrandEntity brand = brandService.getById(vo.getBrandId());
                SpuInfoDescEntity desc = spuInfoDescService.getOne(Wrappers.<SpuInfoDescEntity>lambdaQuery()
                        .eq(SpuInfoDescEntity::getSpuId, vo.getId()));
                vo.setBrandName(brand.getName());
                vo.setPic(desc.getDecript());
            }
        }
        return vo;
    }


    /**
     * 查询商品信息  过滤不需要检索的商品
     *
     * @param spuId
     * @return
     */
    private List<SkuEsModel.Attrs> getAttrs(Long spuId) {
        List<ProductAttrValueEntity> productAttrValueEntities = productAttrValueService.list(Wrappers.<ProductAttrValueEntity>lambdaQuery()
                .eq(ProductAttrValueEntity::getSpuId, spuId));

        List<Long> attrIds = productAttrValueEntities.stream().map(ProductAttrValueEntity::getAttrId).toList();

        List<AttrEntity> attrEntityList = attrService.list(Wrappers.<AttrEntity>lambdaQuery()
                .in(AttrEntity::getAttrId, attrIds));

        List<Long> attrIds2 = attrEntityList.stream().filter(po -> Objects.equals(po.getSearchType(), 1)).map(AttrEntity::getAttrId).toList();

        List<SkuEsModel.Attrs> attrs;

        if (CollUtil.isNotEmpty(attrIds2)) {
            List<ProductAttrValueEntity> productAttrValueEntities2 = productAttrValueEntities.stream().filter(po -> attrIds2.contains(po.getAttrId())).toList();


            if (CollUtil.isNotEmpty(productAttrValueEntities2)) {
                attrs = CopyBean.copyBeanList(productAttrValueEntities2, SkuEsModel.Attrs.class);
                return attrs;
            }
        }
        return null;
    }

}